package org.alwayssuper.protocol.codec;

import org.alwayssuper.netmc.codec.MessageDecoder;
import org.alwayssuper.netmc.codec.MessageEncoder;
import org.alwayssuper.netmc.session.Session;
import org.alwayssuper.protocol.commons.GBTResponseType;
import org.alwayssuper.protostar.SchemaManager;
import org.alwayssuper.protostar.util.Explain;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import lombok.extern.slf4j.Slf4j;
import org.alwayssuper.protocol.basics.GBTMessage;

/**
 * GBT协议消息适配器
 * @author alwaysSuper
 */
@Slf4j
public class GBTMessageAdapter  implements MessageEncoder<GBTMessage>, MessageDecoder<GBTMessage> {

    private final GBTMessageEncoder messageEncoder;

    private final GBTMessageDecoder messageDecoder;

    public GBTMessageAdapter(String... basePackages) {
        this(new SchemaManager(basePackages));
    }

    public GBTMessageAdapter(SchemaManager schemaManager) {
        this(new GBTMessageEncoder(schemaManager), new GBTMessageDecoder(schemaManager));
    }

    public GBTMessageAdapter(GBTMessageEncoder messageEncoder, GBTMessageDecoder messageDecoder) {
        this.messageEncoder = messageEncoder;
        this.messageDecoder = messageDecoder;
    }

    public ByteBuf encode(GBTMessage message, Explain explain) {
        return messageEncoder.encode(message, explain);
    }

    public GBTMessage decode(ByteBuf input, Explain explain) {
        return messageDecoder.decode(input, explain);
    }

    public ByteBuf encode(GBTMessage message) {
        return messageEncoder.encode(message);
    }

    public GBTMessage decode(ByteBuf input) {
        return messageDecoder.decode(input);
    }

    @Override
    public ByteBuf encode(GBTMessage message, Session session) {
        ByteBuf output = messageEncoder.encode(message);
        encodeLog(session, message, output);
        return output;
    }

    @Override
    public GBTMessage decode(ByteBuf input, Session session) {
        GBTMessage message = messageDecoder.decode(input);
        if (message != null)
            message.setSession(session);
        decodeLog(session, message, input);
        return message;
    }

    public void encodeLog(Session session, GBTMessage message, ByteBuf output) {
        if (log.isInfoEnabled()){
            if(message.getResponseType() != GBTResponseType.命令 ){
                log.info("{}\n>>>>>-消息应答：{},hex[{}]", session, message, ByteBufUtil.hexDump(output));
            }else {
                log.info("{}\n>>>>>-指令下行：{},hex[{}]", session, message, ByteBufUtil.hexDump(output));
            }
        }
    }

    public void decodeLog(Session session, GBTMessage message, ByteBuf input) {
        if (log.isInfoEnabled())
            log.info("{}\n<<<<<-{},hex[{}]", session, message, ByteBufUtil.hexDump(input, 0, input.writerIndex()));
    }
}
